﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AMail.Common.Interfaces.Data;
using LumiSoft.Net.Mime;
using Elentok.Common;

namespace AMail.Modules.Data.Internals
{
  public class MailAttachment : IMailAttachment
  {
    public IMailMessage OwnerMessage { get; private set; }
    protected MimeEntity MimeEntity { get; private set; }

    public MailAttachment(MimeEntity mimeEntity, IMailMessage ownerMessage)
    {
      this.OwnerMessage = ownerMessage;
      this.MimeEntity = mimeEntity;

      #region Parse Data
      try
      {
        this.Data = new ArrayWrapper<byte>(mimeEntity.Data);
      }
      catch (FormatException)
      {
        byte[] noZeroPadding = this.MimeEntity.DataEncoded.Where(b => b != 0).ToArray();
        byte[] normal = Convert.FromBase64String(this.Encoding.GetString(noZeroPadding));
        this.Data = new ArrayWrapper<byte>(normal);
      }
      #endregion

      UpdateAttachmentType(mimeEntity);
    }

    private void UpdateAttachmentType(MimeEntity mimeEntity)
    {
      switch (mimeEntity.ContentType)
      {
        case MediaType_enum.Text:
        case MediaType_enum.Text_plain:
          this.Type = AttachmentType.Text;
          break;

        case MediaType_enum.Text_html:
          this.Type = AttachmentType.HTML;
          break;

        case MediaType_enum.Text_rtf:
          this.Type = AttachmentType.RTF;
          break;

        case MediaType_enum.Text_xml:
          this.Type = AttachmentType.XML;
          break;

        case MediaType_enum.Audio:
          this.Type = AttachmentType.Audio;
          break;

        case MediaType_enum.Image:
        case MediaType_enum.Image_gif:
        case MediaType_enum.Image_jpeg:
        case MediaType_enum.Image_tiff:
          this.Type = AttachmentType.Image;
          break;

        case MediaType_enum.Video:
          this.Type = AttachmentType.Video;
          break;

        case MediaType_enum.Application:
        case MediaType_enum.Application_octet_stream:
          this.Type = AttachmentType.Application;
          break;
        
        default:
          this.Type = AttachmentType.Unknown;
          break;
      }
    }

    #region IMailAttachment Members

    public AttachmentType Type
    {
      get;
      private set;
    }

    public IArrayWrapper<byte> Data
    {
      get;
      private set;
    }

    public int Size
    {
      get
      {
        if (this.Data == null || this.Data.ToArray() == null)
          return 0;

        return this.Data.ToArray().Length;
      }
    }

    public string Title
    {
      get
      {
        if (!string.IsNullOrEmpty(this.MimeEntity.ContentType_Name))
          return this.MimeEntity.ContentType_Name;
        else if (!string.IsNullOrEmpty(this.MimeEntity.ContentDisposition_FileName))
          return this.MimeEntity.ContentDisposition_FileName;

        return this.MimeEntity.Subject;
      }
    }

    #endregion

    public Encoding Encoding
    {
      get
      {
        if (this.OwnerMessage.Encoding != null)
          return this.OwnerMessage.Encoding;

        if (!string.IsNullOrEmpty(this.MimeEntity.ContentType_CharSet))
          return Encoding.GetEncoding(this.MimeEntity.ContentType_CharSet);

        return Encoding.UTF8;
      }
    }

    public string Text
    {
      get
      {
        return this.Encoding.GetString(this.Data.ToArray());
        //try
        //{
        //  return this.Encoding.GetString(this.MimeEntity.Data);
        //}
        //catch (FormatException)
        //{
        //  byte[] noZeroPadding = this.MimeEntity.DataEncoded.Filter(b => b != 0);
        //  byte[] normal = Convert.FromBase64String(this.Encoding.GetString(noZeroPadding));
        //  return this.Encoding.GetString(normal);
        //}
      }
    }
  }
}
